﻿using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Letter.IO.Binary;

public static class FixedWriteExtensions
{
    private static BinaryOrderOperationLE LE
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        get { return BinaryOrderOperationLE.Instance; }
    }
    private static BinaryOrderOperationBE BE
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        get { return BinaryOrderOperationBE.Instance; }
    }
    
    
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteBoolean(this Span<byte> span, bool value)
    {
        span.FWriteUInt8(value ? (byte)1 : (byte)0);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteChar(this Span<byte> span, char value)
    {
        span.FWriteCharBE(value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteCharLE(this Span<byte> span, char value)
    {
        LE.WriteChar(span, value);
    }
    
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteCharBE(this Span<byte> span, char value)
    {
        BE.WriteChar(span, value);
    }
    
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteInt8(this Span<byte> span, sbyte value)
    {
        span.FWriteUInt8((byte) value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteUInt8(this Span<byte> span, byte value)
    {
        MemoryMarshal.Write<byte>(span, ref value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteInt16LE(this Span<byte> span, short value)
    {
        LE.WriteInt16(span, value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteInt16BE(this Span<byte> span, short value)
    {
        BE.WriteInt16(span, value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteUInt16LE(this Span<byte> span, ushort value)
    {
        LE.WriteUInt16(span, value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteUInt16BE(this Span<byte> span, ushort value)
    {
        BE.WriteUInt16(span, value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteInt32LE(this Span<byte> span, int value)
    {
        LE.WriteInt32(span, value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteInt32BE(this Span<byte> span, int value)
    {
        BE.WriteInt32(span, value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteUInt32LE(this Span<byte> span, uint value)
    {
        LE.WriteUInt32(span, value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteUInt32BE(this Span<byte> span, uint value)
    {
        BE.WriteUInt32(span, value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteInt64LE(this Span<byte> span, long value)
    {
        LE.WriteInt64(span, value);
    }
    
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteInt64BE(this Span<byte> span, long value)
    {
        BE.WriteInt64(span, value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteUInt64LE(this Span<byte> span, ulong value)
    {
        LE.WriteUInt64(span, value);
    }
    
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteUInt64BE(this Span<byte> span, ulong value)
    {
        BE.WriteUInt64(span, value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteFloat32LE(this Span<byte> span, float value)
    {
        LE.WriteFloat32(span, value);
    }
    
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteFloat32BE(this Span<byte> span, float value)
    {
        BE.WriteFloat32(span, value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteFloat64LE(this Span<byte> span, double value)
    {
        LE.WriteFloat64(span, value);
    }
    
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteFloat64BE(this Span<byte> span, double value)
    {
        BE.WriteFloat64(span, value);
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FWriteSpan(this Span<byte> span, in ReadOnlySpan<byte> value)
    {
        value.CopyTo(span);
    }
}